package com.lineage.server.model;

import com.lineage.DatabaseFactory;
import com.lineage.config.ConfigRate;
import com.lineage.data.event.ProtectorSet;
import com.lineage.data.item_armor.set.ArmorSet;
import com.lineage.server.clientpackets.C_LoginToServer;
import com.lineage.server.datatables.InnKeyTable;
import com.lineage.server.datatables.ItemRestrictionsTable;
import com.lineage.server.datatables.ItemSpecialAttributeTable;
import com.lineage.server.datatables.ItemTable;
import com.lineage.server.datatables.ItemVIPTable;
import com.lineage.server.datatables.RewardArmorTable;
import com.lineage.server.datatables.RewardWeaponTable;
import com.lineage.server.datatables.lock.CharItemsReading;
import com.lineage.server.model.Instance.L1ItemInstance;
import com.lineage.server.model.Instance.L1PcInstance;
import com.lineage.server.model.Instance.L1PetInstance;
import com.lineage.server.serverpackets.S_AddItem;
import com.lineage.server.serverpackets.S_CharVisualUpdate;
import com.lineage.server.serverpackets.S_DeleteInventoryItem;
import com.lineage.server.serverpackets.S_ItemColor;
import com.lineage.server.serverpackets.S_ItemName;
import com.lineage.server.serverpackets.S_ItemStatus;
import com.lineage.server.serverpackets.S_OwnCharStatus;
import com.lineage.server.serverpackets.S_PacketBox;
import com.lineage.server.serverpackets.S_ServerMessage;
import com.lineage.server.serverpackets.ServerBasePacket;
import com.lineage.server.templates.L1Item;
import com.lineage.server.templates.L1ItemSpecialAttribute;
import com.lineage.server.templates.L1ItemSpecialAttributeChar;
import com.lineage.server.utils.SQLUtil;
import com.lineage.server.world.World;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
import java.util.Random;
import java.util.concurrent.CopyOnWriteArrayList;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

public class L1PcInventory extends L1Inventory {
  public static final int COL_SEAL = 4096;
  
  public static final int COL_ATTR_ENCHANT_LEVEL = 2048;
  
  public static final int COL_ATTR_ENCHANT_KIND = 1024;
  
  public static final int COL_BLESS = 512;
  
  public static final int COL_REMAINING_TIME = 256;
  
  public static final int COL_CHARGE_COUNT = 128;
  
  public static final int COL_ITEMID = 64;
  
  public static final int COL_DELAY_EFFECT = 32;
  
  public static final int COL_COUNT = 16;
  
  public static final int COL_EQUIPPED = 8;
  
  public static final int COL_ENCHANTLVL = 4;
  
  public static final int COL_IS_ID = 2;
  
  public static final int COL_DURABILITY = 1;
  
  private static final Log _log = LogFactory.getLog(L1PcInventory.class);
  
  private static final long serialVersionUID = 1L;
  
  private static final int MAX_SIZE = 180;
  
  private final L1PcInstance _owner;
  
  private int _arrowId;
  
  private int _stingId;
  
  public L1PcInventory(L1PcInstance owner) {
    this._owner = owner;
    this._arrowId = 0;
    this._stingId = 0;
  }
  
  public L1PcInstance getOwner() {
    return this._owner;
  }
  
  public int getWeight240() {
    return calcWeight240(getWeight());
  }
  
  public int calcWeight240(long weight) {
    int weight2 = 0;
    if (ConfigRate.RATE_WEIGHT_LIMIT != 0.0D) {
      double maxWeight = this._owner.getMaxWeight();
      if (weight > maxWeight) {
        weight2 = 240;
      } else {
        double wpTemp = (weight * 100L) / maxWeight * 240.0D / 100.0D;
        DecimalFormat df = new DecimalFormat("00.##");
        df.format(wpTemp);
        wpTemp = Math.round(wpTemp);
        weight2 = (int)wpTemp;
      } 
    } else {
      weight2 = 0;
    } 
    return weight2;
  }
  
  public int checkAddItem(L1ItemInstance item, long count) {
    return checkAddItem(item, count, true);
  }
  
  public int checkAddItem(L1Item item, long count) {
    if (item == null)
      return -1; 
    boolean isMaxSize = false;
    boolean isWeightOver = false;
    if (item.isStackable()) {
      if (!checkItem(item.getItemId()) && getSize() + 1 >= 180)
        isMaxSize = true; 
    } else if (getSize() + 1 >= 180) {
      isMaxSize = true;
    } 
    if (isMaxSize) {
      sendOverMessage(263);
      return 1;
    } 
    long weight = getWeight() + item.getWeight() * count / 1000L + 1L;
    if (weight < 0L || item.getWeight() * count / 1000L < 0L)
      isWeightOver = true; 
    if (calcWeight240(weight) >= 240 && !isWeightOver)
      isWeightOver = true; 
    if (isWeightOver) {
      sendOverMessage(82);
      return 2;
    } 
    return 0;
  }
  
  public int checkAddItem(L1ItemInstance item, long count, boolean message) {
    if (item == null)
      return -1; 
    if (count <= 0L)
      return -1; 
    boolean isMaxSize = false;
    boolean isWeightOver = false;
    if (item.isStackable()) {
      if (!checkItem(item.getItem().getItemId()) && getSize() + 1 >= 180)
        isMaxSize = true; 
    } else if (getSize() + 1 >= 180) {
      isMaxSize = true;
    } 
    if (isMaxSize) {
      if (message)
        sendOverMessage(263); 
      return 1;
    } 
    long weight = getWeight() + item.getItem().getWeight() * count / 1000L + 1L;
    if (weight < 0L || item.getItem().getWeight() * count / 1000L < 0L)
      isWeightOver = true; 
    if (calcWeight240(weight) >= 240 && !isWeightOver)
      isWeightOver = true; 
    if (isWeightOver) {
      if (message)
        sendOverMessage(82); 
      return 2;
    } 
    return 0;
  }
  
  public void sendOverMessage(int message_id) {
    this._owner.sendPackets((ServerBasePacket)new S_ServerMessage(message_id));
  }
  
  public int getTypeAndItemIdEquipped(int type2, int type, int itemId) {
    int equipeCount = 0;
    L1ItemInstance item = null;
    Iterator<L1ItemInstance> iterator = this._items.iterator();
    while (iterator.hasNext()) {
      Object itemObject = iterator.next();
      item = (L1ItemInstance)itemObject;
      if (item.getItem().getType2() == type2 && item.getItem().getType() == type && item.getItemId() == itemId && 
        item.isEquipped())
        equipeCount++; 
    } 
    return equipeCount;
  }
  
  public int getTypeAndItemIdEquippedgroup(int group) {
    int equipeCount = 0;
    L1ItemInstance item = null;
    Iterator<L1ItemInstance> iterator = this._items.iterator();
    while (iterator.hasNext()) {
      Object itemObject = iterator.next();
      item = (L1ItemInstance)itemObject;
      if (item.isEquipped() && item.getItem().getgroup() == group)
        equipeCount++; 
    } 
    return equipeCount;
  }
  
  public void loadItems() {
    try {
      CopyOnWriteArrayList<L1ItemInstance> items = CharItemsReading.get()
        .loadItems(Integer.valueOf(this._owner.getId()));
      if (items != null) {
        this._items = items;
        List<L1ItemInstance> equipped = new CopyOnWriteArrayList<>();
        Iterator<L1ItemInstance> iterator = items.iterator();
        while (iterator.hasNext()) {
          L1ItemInstance item = iterator.next();
          int itemId = item.getItemId();
          if (item.isEquipped()) {
            if (ItemVIPTable.get().checkVIP(itemId))
              ItemVIPTable.get().addItemVIP(this._owner, itemId); 
            equipped.add(item);
          } 
          item.setEquipped(false);
        } 
        Iterator<L1ItemInstance> iterator2 = equipped.iterator();
        while (iterator2.hasNext()) {
          L1ItemInstance item = iterator2.next();
          setEquipped(item, true, true, false);
        } 
      } 
    } catch (Exception e) {
      _log.error(e.getLocalizedMessage(), e);
    } 
  }
  
  public void insertItem(L1ItemInstance item) {
    int itemId = item.getItemId();
    if (item.getCount() <= 0L)
      return; 
    item.set_char_objid(this._owner.getId());
    this._owner.sendPackets((ServerBasePacket)new S_AddItem(item));
    if (item.getItem().getWeight() != 0)
      this._owner.sendPackets((ServerBasePacket)new S_PacketBox(10, getWeight240())); 
    try {
      CharItemsReading.get().storeItem(this._owner.getId(), item);
    } catch (Exception e) {
      _log.error(e.getLocalizedMessage(), e);
    } 
  }
  
  public void updateItem(L1ItemInstance item) {
    updateItem(item, 16);
    if (item.getItem().isToBeSavedAtOnce())
      saveItem(item, 16); 
  }
  
  public void updateItem(L1ItemInstance item, int column) {
    if (column >= 4096) {
      this._owner.sendPackets((ServerBasePacket)new S_ItemName(item));
      column -= 4096;
    } 
    if (column >= 2048) {
      this._owner.sendPackets((ServerBasePacket)new S_ItemStatus(item));
      column -= 2048;
    } 
    if (column >= 1024) {
      this._owner.sendPackets((ServerBasePacket)new S_ItemStatus(item));
      column -= 1024;
    } 
    if (column >= 512) {
      this._owner.sendPackets((ServerBasePacket)new S_ItemColor(item));
      column -= 512;
    } 
    if (column >= 256) {
      this._owner.sendPackets((ServerBasePacket)new S_ItemName(item));
      column -= 256;
    } 
    if (column >= 128) {
      this._owner.sendPackets((ServerBasePacket)new S_ItemName(item));
      column -= 128;
    } 
    if (column >= 64) {
      this._owner.sendPackets((ServerBasePacket)new S_ItemStatus(item));
      this._owner.sendPackets((ServerBasePacket)new S_ItemColor(item));
      this._owner.sendPackets((ServerBasePacket)new S_PacketBox(10, getWeight240()));
      column -= 64;
    } 
    if (column >= 32)
      column -= 32; 
    if (column >= 16) {
      this._owner.sendPackets((ServerBasePacket)new S_ItemStatus(item));
      int weight = item.getWeight();
      if (weight != item.getLastWeight()) {
        item.setLastWeight(weight);
        this._owner.sendPackets((ServerBasePacket)new S_ItemStatus(item));
      } else {
        this._owner.sendPackets((ServerBasePacket)new S_ItemName(item));
      } 
      if (item.getItem().getWeight() != 0)
        this._owner.sendPackets((ServerBasePacket)new S_PacketBox(10, getWeight240())); 
      column -= 16;
    } 
    if (column >= 8) {
      this._owner.sendPackets((ServerBasePacket)new S_ItemName(item));
      column -= 8;
    } 
    if (column >= 4) {
      this._owner.sendPackets((ServerBasePacket)new S_ItemStatus(item));
      column -= 4;
    } 
    if (column >= 2) {
      this._owner.sendPackets((ServerBasePacket)new S_ItemStatus(item));
      this._owner.sendPackets((ServerBasePacket)new S_ItemColor(item));
      column -= 2;
    } 
    if (column >= 1) {
      this._owner.sendPackets((ServerBasePacket)new S_ItemStatus(item));
      column--;
    } 
  }
  
  public void saveItem(L1ItemInstance item, int column) {
    if (column == 0)
      return; 
    try {
      if (column >= 4096) {
        CharItemsReading.get().updateItemSeal(item);
        column -= 4096;
      } 
      if (column >= 2048) {
        CharItemsReading.get().updateItemAttrEnchantLevel(item);
        column -= 2048;
      } 
      if (column >= 1024) {
        CharItemsReading.get().updateItemAttrEnchantKind(item);
        column -= 1024;
      } 
      if (column >= 512) {
        CharItemsReading.get().updateItemBless(item);
        column -= 512;
      } 
      if (column >= 256) {
        CharItemsReading.get().updateItemRemainingTime(item);
        column -= 256;
      } 
      if (column >= 128) {
        CharItemsReading.get().updateItemChargeCount(item);
        column -= 128;
      } 
      if (column >= 64) {
        CharItemsReading.get().updateItemId(item);
        column -= 64;
      } 
      if (column >= 32) {
        CharItemsReading.get().updateItemDelayEffect(item);
        column -= 32;
      } 
      if (column >= 16) {
        CharItemsReading.get().updateItemCount(item);
        column -= 16;
      } 
      if (column >= 8) {
        CharItemsReading.get().updateItemEquipped(item);
        column -= 8;
      } 
      if (column >= 4) {
        CharItemsReading.get().updateItemEnchantLevel(item);
        column -= 4;
      } 
      if (column >= 2) {
        CharItemsReading.get().updateItemIdentified(item);
        column -= 2;
      } 
      if (column >= 1) {
        CharItemsReading.get().updateItemDurability(item);
        column--;
      } 
    } catch (Exception e) {
      _log.error(e.getLocalizedMessage(), e);
    } 
  }
  
  public void deleteItem(L1ItemInstance item) {
    try {
      CharItemsReading.get().deleteItem(this._owner.getId(), item);
    } catch (Exception e) {
      _log.error(e.getLocalizedMessage(), e);
    } 
    int itemid = item.getItemId();
    if (itemid == 40312)
      InnKeyTable.DeleteKey(item); 
    if (itemid == 82503)
      InnKeyTable.DeleteKey(item); 
    if (itemid == 82504)
      InnKeyTable.DeleteKey(item); 
    if (itemid == ProtectorSet.ITEM_ID && this instanceof L1PcInventory) {
      L1PcInventory pc_inv = this;
      L1PcInstance pc = pc_inv.getOwner();
      if (pc.isProtector()) {
        pc.setProtector(false);
        World.get().broadcastPacketToAll((ServerBasePacket)new S_ServerMessage(2925));
      } 
    } 
    if (itemid == 56148 && this instanceof L1PcInventory) {
      L1PcInventory pc_inv = this;
      L1PcInstance pc = pc_inv.getOwner();
      if (pc.isEffectGS()) {
        pc.setGS(false);
        C_LoginToServer.checkforDADISStone(pc);
      } 
    } 
    if (itemid == 56147 && this instanceof L1PcInventory) {
      L1PcInventory pc_inv = this;
      L1PcInstance pc = pc_inv.getOwner();
      if (pc.isEffectDADIS()) {
        pc.setDADIS(false);
        C_LoginToServer.checkforDADISStone(pc);
      } 
    } 
    if (itemid == 44216 && this instanceof L1PcInventory) {
      L1PcInventory pc_inv = this;
      L1PcInstance pc = pc_inv.getOwner();
      if (pc._isCraftsmanHeirloom()) {
        pc.setCraftsmanHeirloom(false);
        C_LoginToServer.checkforSouls(pc);
      } 
    } 
    if (itemid == 44217 && this instanceof L1PcInventory) {
      L1PcInventory pc_inv = this;
      L1PcInstance pc = pc_inv.getOwner();
      if (pc._isMarsSoul()) {
        pc.setMarsSoul(false);
        C_LoginToServer.checkforSouls(pc);
      } 
    } 
    if (item.isEquipped())
      setEquipped(item, false); 
    if (item != null) {
      this._owner.sendPackets((ServerBasePacket)new S_DeleteInventoryItem(item));
      this._items.remove(item);
      if (item.getItem().getWeight() != 0)
        this._owner.sendPackets((ServerBasePacket)new S_PacketBox(10, getWeight240())); 
    } 
  }
  
  public void setEquipped(L1ItemInstance item, boolean equipped) {
    setEquipped(item, equipped, false, false);
  }
  
  public void setEquipped(L1ItemInstance item, boolean equipped, boolean loaded, boolean changeWeapon) {
    if (item.isEquipped() != equipped) {
      if (equipped) {
        item.setEquipped(true);
        this._owner.getEquipSlot().set(item);
      } else {
        if (!loaded && (item.getItemId() == 20077 || item.getItemId() == 20062 || item.getItemId() == 120077) && 
          this._owner.isInvisble()) {
          this._owner.delInvis();
          return;
        } 
        item.setEquipped(false);
        this._owner.getEquipSlot().remove(item);
      } 
      if (!loaded) {
        this._owner.getInventory().toSlotPacket(this._owner, item);
        this._owner.setCurrentHp(this._owner.getCurrentHp());
        this._owner.setCurrentMp(this._owner.getCurrentMp());
        updateItem(item, 8);
        this._owner.sendPackets((ServerBasePacket)new S_OwnCharStatus(this._owner));
        if (item.getItem().getType2() == 1 && !changeWeapon)
          this._owner.sendPacketsAll((ServerBasePacket)new S_CharVisualUpdate(this._owner)); 
      } 
      if (item.getItem().get_safeenchant() >= 0 && item.getEnchantLevel() >= item.getItem().get_safeenchant()) {
        int level = item.getEnchantLevel() - item.getItem().get_safeenchant();
        if (item.getItem().getType2() == 1) {
          RewardWeaponTable.forWeapon(this._owner, item, level, equipped);
        } else if (item.getItem().getUseType() == 2 || item.getItem().getUseType() == 18 || 
          item.getItem().getUseType() == 19 || item.getItem().getUseType() == 20 || 
          item.getItem().getUseType() == 21 || item.getItem().getUseType() == 22 || 
          item.getItem().getUseType() == 25 || item.getItem().getUseType() == 47) {
          RewardArmorTable.forArmor(this._owner, item, level, equipped);
        } 
      } 
    } 
  }
  
  public L1ItemInstance checkEquippedItem(int id) {
    try {
      Iterator<L1ItemInstance> iterator = this._items.iterator();
      while (iterator.hasNext()) {
        L1ItemInstance item = iterator.next();
        if (item.getItem().getItemId() == id && item.isEquipped())
          return item; 
      } 
    } catch (Exception ex) {
      _log.error(ex.getLocalizedMessage(), ex);
    } 
    return null;
  }
  
  public boolean checkEquipped(int id) {
    try {
      Iterator<L1ItemInstance> iterator = this._items.iterator();
      while (iterator.hasNext()) {
        L1ItemInstance item = iterator.next();
        if (item.getItem().getItemId() == id && item.isEquipped())
          return true; 
      } 
    } catch (Exception ex) {
      _log.error(ex.getLocalizedMessage(), ex);
    } 
    return false;
  }
  
  public boolean checkSkillType(int i) {
    Iterator<L1ItemInstance> iterator = this._items.iterator();
    while (iterator.hasNext()) {
      L1ItemInstance item = iterator.next();
      item.getskilltype();
      if (item.getskilltype() == i && item.isEquipped())
        return true; 
    } 
    return false;
  }
  
  public boolean checkSkillTypelv(int i) {
    Iterator<L1ItemInstance> iterator = this._items.iterator();
    while (iterator.hasNext()) {
      L1ItemInstance item = iterator.next();
      item.getskilltypelv();
      if (item.getskilltypelv() == i && item.isEquipped())
        return true; 
    } 
    return false;
  }
  
  public boolean checkSkillTypebless(int i) {
    Iterator<L1ItemInstance> iterator = this._items.iterator();
    while (iterator.hasNext()) {
      L1ItemInstance item = iterator.next();
      item.getBless();
      if (item.getBless() == i && item.isEquipped())
        return true; 
    } 
    return false;
  }
  
  public boolean checkCardEquipped(int itemid) {
    try {
      Iterator<L1ItemInstance> iterator = this._items.iterator();
      while (iterator.hasNext()) {
        L1ItemInstance item = iterator.next();
        if (item.getItem().getItemId() == itemid && item.get_card_use() == 1)
          return true; 
      } 
    } catch (Exception ex) {
      _log.error(ex.getLocalizedMessage(), ex);
    } 
    return false;
  }
  
  public boolean checkEquipped(String nameid) {
    try {
      Iterator<L1ItemInstance> iterator = this._items.iterator();
      while (iterator.hasNext()) {
        L1ItemInstance item = iterator.next();
        if (item.getName().equals(nameid) && item.isEquipped())
          return true; 
      } 
    } catch (Exception ex) {
      _log.error(ex.getLocalizedMessage(), ex);
    } 
    return false;
  }
  
  public boolean checkEquipped(int[] ids) {
    try {
      int length = ids.length;
      int i = 0;
      while (i < length) {
        int id = ids[i];
        if (!checkEquipped(id))
          return false; 
        i++;
      } 
    } catch (Exception ex) {
      _log.error(ex.getLocalizedMessage(), ex);
    } 
    return true;
  }
  
  public boolean checkEquipped(String[] names) {
    try {
      int length = names.length;
      int i = 0;
      while (i < length) {
        String name = names[i];
        if (!checkEquipped(name))
          return false; 
        i++;
      } 
    } catch (Exception ex) {
      _log.error(ex.getLocalizedMessage(), ex);
    } 
    return true;
  }
  
  public int getTypeEquipped(int type2, int type) {
    int equipeCount = 0;
    try {
      Iterator<L1ItemInstance> iterator = this._items.iterator();
      while (iterator.hasNext()) {
        L1ItemInstance item = iterator.next();
        if (item.getItem().getType2() == type2 && item.getItem().getType() == type && item.isEquipped())
          equipeCount++; 
      } 
    } catch (Exception ex) {
      _log.error(ex.getLocalizedMessage(), ex);
    } 
    return equipeCount;
  }
  
  public L1ItemInstance getItemEquipped(int type2, int type) {
    L1ItemInstance equipeitem = null;
    try {
      Iterator<L1ItemInstance> iterator = this._items.iterator();
      while (iterator.hasNext()) {
        L1ItemInstance item = iterator.next();
        if (item.getItem().getType2() == type2 && item.getItem().getType() == type && item.isEquipped()) {
          equipeitem = item;
          break;
        } 
      } 
    } catch (Exception ex) {
      _log.error(ex.getLocalizedMessage(), ex);
    } 
    return equipeitem;
  }
  
  public L1ItemInstance getItemEquipped1(int type2) {
    L1ItemInstance equipeitem = null;
    try {
      Iterator<L1ItemInstance> iterator = this._items.iterator();
      while (iterator.hasNext()) {
        L1ItemInstance item = iterator.next();
        if (item.getItem().getType2() == type2 && item.isEquipped()) {
          equipeitem = item;
          break;
        } 
      } 
    } catch (Exception ex) {
      _log.error(ex.getLocalizedMessage(), ex);
    } 
    return equipeitem;
  }
  
  public void setPartMode(ArmorSet armorSet, boolean isMode) {
    int tgItemId = armorSet.get_ids()[0];
    L1ItemInstance[] tgItems = findItemsId(tgItemId);
    L1ItemInstance[] array;
    int length = (array = tgItems).length;
    int i = 0;
    while (i < length) {
      L1ItemInstance tgItem = array[i];
      tgItem.setIsMatch(isMode);
      this._owner.sendPackets((ServerBasePacket)new S_ItemStatus(tgItem));
      i++;
    } 
  }
  
  public L1ItemInstance[] getRingEquipped() {
    L1ItemInstance[] equipeItem = new L1ItemInstance[4];
    try {
      int equipeCount = 0;
      Iterator<L1ItemInstance> iterator = this._items.iterator();
      while (iterator.hasNext()) {
        L1ItemInstance item = iterator.next();
        if (item.getItem().getUseType() == 23 && item.isEquipped()) {
          equipeItem[equipeCount] = item;
          if (++equipeCount == 4)
            break; 
        } 
      } 
    } catch (Exception ex) {
      _log.error(ex.getLocalizedMessage(), ex);
    } 
    return equipeItem;
  }
  
  public L1ItemInstance[] getEarRingEquipped() {
    L1ItemInstance[] equipeItem = new L1ItemInstance[2];
    try {
      int equipeCount = 0;
      Iterator<L1ItemInstance> iterator = this._items.iterator();
      while (iterator.hasNext()) {
        L1ItemInstance item = iterator.next();
        if (item.getItem().getUseType() == 40 && item.isEquipped()) {
          equipeItem[equipeCount] = item;
          if (++equipeCount == 2)
            break; 
        } 
      } 
    } catch (Exception ex) {
      _log.error(ex.getLocalizedMessage(), ex);
    } 
    return equipeItem;
  }
  
  public void takeoffEquip(int polyid) {
    takeoffWeapon(polyid);
    takeoffArmor(polyid);
  }
  
  private void takeoffWeapon(int polyid) {
    if (this._owner.getWeapon() == null)
      return; 
    boolean takeoff = false;
    int weapon_type = this._owner.getWeapon().getItem().getType();
    takeoff = !L1PolyMorph.isEquipableWeapon(polyid, weapon_type);
    if (takeoff)
      setEquipped(this._owner.getWeapon(), false, false, false); 
  }
  
  private void takeoffArmor(int polyid) {
    L1ItemInstance armor = null;
    int type = 0;
    while (type <= 13) {
      if (getTypeEquipped(2, type) != 0 && !L1PolyMorph.isEquipableArmor(polyid, type))
        if (type == 9) {
          armor = getItemEquipped(2, type);
          if (armor != null)
            setEquipped(armor, false, false, false); 
          armor = getItemEquipped(2, type);
          if (armor != null)
            setEquipped(armor, false, false, false); 
          armor = getItemEquipped(2, type);
          if (armor != null)
            setEquipped(armor, false, false, false); 
          armor = getItemEquipped(2, type);
          if (armor != null)
            setEquipped(armor, false, false, false); 
        } else if (type == 12) {
          armor = getItemEquipped(2, type);
          if (armor != null)
            setEquipped(armor, false, false, false); 
          armor = getItemEquipped(2, type);
          if (armor != null)
            setEquipped(armor, false, false, false); 
        } else {
          armor = getItemEquipped(2, type);
          if (armor != null)
            setEquipped(armor, false, false, false); 
        }  
      type++;
    } 
  }
  
  public L1ItemInstance getArrow() {
    return getBullet(-2);
  }
  
  public void setArrow(int id) {
    this._arrowId = id;
  }
  
  public L1ItemInstance getSting() {
    return getBullet(-3);
  }
  
  public void setSting(int id) {
    this._stingId = id;
  }
  
  private L1ItemInstance getBullet(int useType) {
    int priorityId = 0;
    if (useType == -2) {
      if (this._owner.getWeapon().getItemId() == 192) {
        L1ItemInstance bullet = findItemId(40742);
        if (bullet == null)
          this._owner.sendPackets((ServerBasePacket)new S_ServerMessage(329, "$2377")); 
        return bullet;
      } 
      priorityId = this._arrowId;
    } 
    if (useType == -3)
      priorityId = this._stingId; 
    if (priorityId > 0) {
      L1ItemInstance bullet = findItemId(priorityId);
      if (bullet != null)
        return bullet; 
      if (useType == -2)
        this._arrowId = 0; 
      if (useType == -3)
        this._stingId = 0; 
    } 
    Iterator<L1ItemInstance> iterator = this._items.iterator();
    while (iterator.hasNext()) {
      Object itemObject = iterator.next();
      L1ItemInstance bullet = (L1ItemInstance)itemObject;
      if (bullet.getItem().getUseType() == useType) {
        if (useType == -2)
          this._arrowId = bullet.getItem().getItemId(); 
        if (useType == -3)
          this._stingId = bullet.getItem().getItemId(); 
        return bullet;
      } 
    } 
    return null;
  }
  
  public int hpRegenPerTick() {
    int hpr = 0;
    try {
      Iterator<L1ItemInstance> iterator = this._items.iterator();
      while (iterator.hasNext()) {
        Object itemObject = iterator.next();
        L1ItemInstance item = (L1ItemInstance)itemObject;
        if (item.isEquipped()) {
          L1ItemSpecialAttributeChar attr_char = item.get_ItemAttrName();
          if (attr_char != null) {
            L1ItemSpecialAttribute attr = ItemSpecialAttributeTable.get()
              .getAttrId(attr_char.get_attr_id());
            hpr += attr.get_add_hpr() + item.getItem().get_addhpr() + item.getItemHpr();
            continue;
          } 
          hpr += item.getItem().get_addhpr() + item.getItemHpr();
        } 
      } 
    } catch (Exception e) {
      _log.error(e.getLocalizedMessage(), e);
    } 
    return hpr;
  }
  
  public int mpRegenPerTick() {
    int mpr = 0;
    try {
      Iterator<L1ItemInstance> iterator = this._items.iterator();
      while (iterator.hasNext()) {
        Object itemObject = iterator.next();
        L1ItemInstance item = (L1ItemInstance)itemObject;
        if (item.isEquipped()) {
          L1ItemSpecialAttributeChar attr_char = item.get_ItemAttrName();
          if (attr_char != null) {
            L1ItemSpecialAttribute attr = ItemSpecialAttributeTable.get()
              .getAttrId(attr_char.get_attr_id());
            mpr += attr.get_add_mpr() + item.getMpr() + item.getItemMpr();
            continue;
          } 
          mpr += item.getMpr() + item.getItemMpr();
        } 
      } 
    } catch (Exception e) {
      _log.error(e.getLocalizedMessage(), e);
    } 
    return mpr;
  }
  
  public L1ItemInstance caoPenalty() {
    try {
      Random random = new Random();
      int rnd = random.nextInt(this._items.size());
      L1ItemInstance penaltyItem = this._items.get(rnd);
      if (penaltyItem.getItem().getItemId() == 44070)
        return null; 
      if (penaltyItem.getItem().getItemId() == 40308)
        return null; 
      if (penaltyItem.getItem().getItemId() == 92088)
        return null; 
      if (penaltyItem.getItem().getItemId() == 83000)
        return null; 
      if (penaltyItem.getItem().getItemId() == 83022)
        return null; 
      if (penaltyItem.getItem().isCantDelete())
        return null; 
      if (!penaltyItem.getItem().isTradable())
        return null; 
      if (penaltyItem.isSeal())
        return null; 
      if (penaltyItem.getItem().isnonodrop())
        return null; 
      if (penaltyItem.get_time() != null)
        return null; 
      if (ItemRestrictionsTable.RESTRICTIONS.contains(Integer.valueOf(penaltyItem.getItemId())))
        return null; 
      Object[] petlist = this._owner.getPetList().values().toArray();
      Object[] array;
      int length = (array = petlist).length;
      int i = 0;
      while (i < length) {
        Object petObject = array[i];
        if (petObject instanceof L1PetInstance) {
          L1PetInstance pet = (L1PetInstance)petObject;
          if (penaltyItem.getId() == pet.getItemObjId())
            return null; 
        } 
        i++;
      } 
      if (this._owner.getDoll(penaltyItem.getId()) != null)
        return null; 
      setEquipped(penaltyItem, false);
      return penaltyItem;
    } catch (Exception e) {
      _log.error(e.getLocalizedMessage(), e);
      return null;
    } 
  }
  
  public void delQuestItem(int itemId) {
    try {
      Random random = new Random();
      Iterator<L1ItemInstance> iterator = this._items.iterator();
      while (iterator.hasNext()) {
        L1ItemInstance item = iterator.next();
        if (item.getItemId() == itemId) {
          removeItem(item);
          this._owner.sendPackets((ServerBasePacket)new S_ServerMessage(random.nextInt(4) + 445, item.getName()));
        } 
      } 
    } catch (Exception e) {
      _log.error(e.getLocalizedMessage(), e);
    } 
  }
  
  public int checkAddItem_LV(L1ItemInstance item, int count, int EnchantLevel) {
    return checkAddItem_LV(item, count, EnchantLevel, true);
  }
  
  public int checkAddItem_LV(L1ItemInstance item, int count, int EnchantLevel, boolean message) {
    if (item == null)
      return -1; 
    if (getSize() > 180 || (
      getSize() == 180 && (!item.isStackable() || !checkItem(item.getItem().getItemId())))) {
      if (message)
        sendOverMessage(263); 
      return 1;
    } 
    int weight = getWeight() + item.getItem().getWeight() * count / 1000 + 1;
    if (weight < 0 || item.getItem().getWeight() * count / 1000 < 0) {
      if (message)
        sendOverMessage(82); 
      return 2;
    } 
    if (calcWeight240(weight) >= 240) {
      if (message)
        sendOverMessage(82); 
      return 2;
    } 
    L1ItemInstance itemExist = findItemId(item.getItemId());
    if (itemExist != null && itemExist.getCount() + count > Long.MAX_VALUE) {
      if (message)
        getOwner().sendPackets((ServerBasePacket)new S_ServerMessage(166, "所持有的金币", "超过了2,000,000,000上限")); 
      return 3;
    } 
    return 0;
  }
  
  public L1ItemInstance checkItemX_Lv(int itemid, int lv, long count) {
    if (count <= 0L)
      return null; 
    if (ItemTable.get().getTemplate(itemid) != null) {
      L1ItemInstance item = findItemIdNoEq(itemid);
      if (item != null && item.getCount() >= count && item.getEnchantLevel() == lv)
        return item; 
    } 
    return null;
  }
  
  public synchronized boolean checkDBItemCount(int pcId, int itemId, long count) {
    Connection con = null;
    PreparedStatement pstm = null;
    ResultSet rs = null;
    long actualcount = 0L;
    try {
      con = DatabaseFactory.get().getConnection();
      pstm = con.prepareStatement("SELECT * FROM character_items WHERE char_id =? AND item_id = ?");
      pstm.setInt(1, pcId);
      pstm.setInt(2, itemId);
      rs = pstm.executeQuery();
      while (rs.next())
        actualcount = rs.getLong("count"); 
    } catch (SQLException e) {
      e.printStackTrace();
    } finally {
      SQLUtil.close(rs, pstm, con);
    } 
    return (actualcount >= count);
  }
  
  public synchronized boolean checkDBResultItemCount(int pcId, int id, int count, int xyz) {
    Connection con = null;
    PreparedStatement pstm = null;
    ResultSet rs = null;
    int actualcount = 0;
    try {
      con = DatabaseFactory.get().getConnection();
      if (xyz == 1) {
        pstm = con.prepareStatement("SELECT * FROM character_warehouse WHERE account_name = ? AND id = ?");
        pstm.setInt(1, pcId);
        pstm.setInt(2, id);
        rs = pstm.executeQuery();
        while (rs.next())
          actualcount = rs.getInt("count"); 
      } else if (xyz == 2) {
        pstm = con.prepareStatement("SELECT * FROM character_elf_warehouse WHERE account_name = ? AND id = ?");
        pstm.setInt(1, pcId);
        pstm.setInt(2, id);
        rs = pstm.executeQuery();
        while (rs.next())
          actualcount = rs.getInt("count"); 
      } else if (xyz == 3) {
        pstm = con.prepareStatement("SELECT * FROM clan_warehouse WHERE clan_name = ? AND id = ?");
        pstm.setInt(1, pcId);
        pstm.setInt(2, id);
        rs = pstm.executeQuery();
        while (rs.next())
          actualcount = rs.getInt("count"); 
      } else if (xyz == 4) {
        pstm = con.prepareStatement("SELECT * FROM character_char_warehouse WHERE char_name = ? AND id = ?");
        pstm.setInt(1, pcId);
        pstm.setInt(2, id);
        rs = pstm.executeQuery();
        while (rs.next())
          actualcount = rs.getInt("count"); 
      } 
    } catch (SQLException e) {
      e.printStackTrace();
    } finally {
      SQLUtil.close(rs, pstm, con);
    } 
    return (actualcount >= count);
  }
  
  public boolean consumeItem(int itemid) {
    if (ItemTable.get().getTemplate(itemid).isStackable()) {
      L1ItemInstance item = findItemId(itemid);
      if (item != null) {
        removeItem(item, item.getCount());
        return true;
      } 
    } else {
      L1ItemInstance[] items = findItemsId(itemid);
      if (items != null) {
        L1ItemInstance[] array;
        int length = (array = items).length;
        int i = 0;
        while (i < length) {
          L1ItemInstance item2 = array[i];
          removeItem(item2);
          i++;
        } 
        return true;
      } 
    } 
    return false;
  }
  
  public void takeoffWeaponFor2600() {
    L1ItemInstance item = this._owner.getInventory().findItemId(1054);
    if (item != null) {
      if (this._owner.getWeapon() != null)
        setEquipped(this._owner.getWeapon(), false, false, false); 
      this._owner.getInventory().setEquipped(item, true);
      L1PolyMorph.doPoly((L1Character)this._owner, 12232, 3600, 1);
    } 
  }
  
  public boolean consumeItemsIdArray(ArrayList<Integer> itemsidarray) {
    int[] itemsid = new int[itemsidarray.size()];
    long[] counts = new long[itemsidarray.size()];
    int i = 0;
    while (i < itemsidarray.size()) {
      itemsid[i] = ((Integer)itemsidarray.get(i)).intValue();
      counts[i] = 1L;
      i++;
    } 
    return consumeItemsId(itemsid, counts);
  }
  
  public boolean consumeItemsId(int[] itemsid, long[] counts) {
    if (itemsid.length != counts.length)
      return false; 
    int removecount = 0;
    int i = 0;
    while (i < itemsid.length) {
      if (ItemTable.get().getTemplate(itemsid[i]).isStackable()) {
        L1ItemInstance item = findItemId(itemsid[i]);
        if (item != null && item.getCount() >= counts[i]) {
          removeItem(item, counts[i]);
          removecount++;
        } 
        if (removecount == itemsid.length)
          return true; 
      } else {
        L1ItemInstance[] itemList = findItemsId(itemsid[i]);
        if (itemList.length == counts[i]) {
          int c = 0;
          while (c < counts[i]) {
            removeItem(itemList[c], 1L);
            c++;
          } 
          if (++removecount == itemsid.length)
            return true; 
        } 
        if (itemList.length > counts[i]) {
          L1Inventory.DataComparator dc = new L1Inventory.DataComparator();
//          L1Inventory.DataComparator dc = new L1Inventory.DataComparator(this);
          Arrays.sort(itemList, dc);
          int c2 = 0;
          while (c2 < counts[i]) {
            removeItem(itemList[c2], 1L);
            c2++;
          } 
          if (++removecount == itemsid.length)
            return true; 
        } 
      } 
      i++;
    } 
    return false;
  }
}
